# -*- coding: utf-8 -*-
import atexit
import sys
import ssl
from pyVim.connect import Disconnect, SmartConnect
from pyVmomi import vim
from pyVim.task import WaitForTask

# vcenter信息
vcenter_ip = "172.16.100.57"
vcenter_port = "443"
vcenter_user = "administrator@vsphere.local"
vcenter_pwd = "Shsnc123!@#"

# 定义要克隆的虚拟机和目标位置
src_vm_name = 'python测试模板机'
dest_vm_name = 'snc-test-imp'

# 要选存储，去掉local
datastore_name = "datastore_100.54"

class vCenterManager():
    def __init__(self, vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd):
        self.vcenter_ip = vcenter_ip
        self.vcenter_port = vcenter_port
        self.vcenter_user = vcenter_user
        self.vcenter_pwd = vcenter_pwd
        self.context = None
        self.si = None
        self.content = None
        # 建立与vSphere的连接
        if hasattr(ssl, '_create_unverified_context'):
            self.context = ssl._create_unverified_context()
        self.si = SmartConnect(host=self.vcenter_ip, port=self.vcenter_port, user=self.vcenter_user,
                               pwd=self.vcenter_pwd, sslContext=self.context)
        self.content = self.si.RetrieveContent()
        if self.si is None:
            print("请检查vc账号密码")
            sys.exit(1)
        atexit.register(Disconnect, self.si)

    def vm_clone(self, src_vmname=None, dest_vmname=None, datastore_name=None):
        if not src_vmname:
            print("源虚拟机设置错误")
            sys.exit(1)

        if not dest_vmname:
            print("目标虚拟机设置错误")
            sys.exit(1)

        # 查找源虚拟机对象
        src_vm = self.get_obj(self.content, [vim.VirtualMachine], src_vmname)
        if not src_vm:
            raise SystemExit("源虚拟机未找到")

        # 配置目标虚拟机的存储位置
        relocate_spec = vim.vm.RelocateSpec()
        datastore = self.get_obj(self.content, [vim.Datastore], datastore_name)
        if not datastore:
            raise SystemExit("存储地址未找到")
        relocate_spec.datastore = datastore

        # 克隆虚拟机的配置
        clone_spec = vim.vm.CloneSpec(
            powerOn=False,  # 克隆后不自动启动
            template=False,  # 克隆后的虚拟机不是模板
            location=relocate_spec
        )

        # 重新配置虚拟机的硬件
        config_spec = vim.vm.ConfigSpec(
            name=dest_vmname,
            memoryMB=4096,
            numCPUs=2,
            deviceChange = []
        )

        # 将 config_spec 添加到 clone_spec 中
        clone_spec.config = config_spec

        # 克隆虚拟机
        task = src_vm.CloneVM_Task(folder=src_vm.parent, name=dest_vmname, spec=clone_spec)
        WaitForTask(task)
        print("Clone task completed")



    # 获取对象通用函数
    def get_obj(self, content, vimtype, name):
        """Get the vsphere object associated with a given text name"""
        obj = None
        container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
        for c in container.view:
            if c.name == name:
                obj = c
                break
        container.Destroy()  # 清理创建的视图
        return obj

if __name__ == '__main__':
    vc = vCenterManager(vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd)
    vc.vm_clone(src_vm_name, dest_vm_name, datastore_name)